﻿using System.Data;
using Zhaoxi.S7Lib;

namespace Zhy.S7LibTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            // 自封装通信库测试
            CustomLib_ReadTest(); // 读取数据demo

            CustomLib_WriteTest(); // 数据写入演示

            CustomLib_Run_Stop(); // 运行和停止演示

            CustomLib_Read_Write_Time(); // 读取和写入时间演示

            Console.ReadLine();

        }

        #region 自定义库通信过程演示 - S7协议
        /// <summary>
        /// 测试PLC读取方法
        /// </summary>
        static void CustomLib_ReadTest()
        {
            S7Client client = new S7Client();
            //client.Connect("192.168.1.100", 0, 0);
            client.Connect("192.168.174.128", 0, 0);
            #region 一次性读取多个不同区域数据
            {
                // 一交性读取多个不同区域的数据
                // DB1.DBW100
                DataParameter dataParameter = new DataParameter(); // 请求参数
                dataParameter.Area = Areas.DB; // 区域
                dataParameter.DBNumber = 1; // 数据库编号
                dataParameter.PVarType = ParameterVarType.DWORD; // 数据类型
                dataParameter.Count = 2; // 数据个数
                dataParameter.ByteAddress = 100; // 数据地址

                // DB1.DBB10
                DataParameter dataParameter2 = new DataParameter(); // 请求参数
                dataParameter2.Area = Areas.DB; // 区域
                dataParameter2.DBNumber = 1; // 数据库编号
                dataParameter2.PVarType = ParameterVarType.BYTE; // 数据类型
                dataParameter2.Count = 3; // 数据个数
                dataParameter2.ByteAddress = 10; // 数据地址

                // Q0.5
                DataParameter dataParameter3 = new DataParameter(); // 请求参数
                dataParameter3.Area = Areas.Q; // 区域
                dataParameter3.PVarType = ParameterVarType.BIT; // 数据类型
                //dataParameter3.Count = 1;// 对于位的操作，数据只能是1，多了是处理不了的
                //dataParameter3.ByteAddress = 0;
                dataParameter3.BitAddress = 5; // 位地址


                DataParameter[] dps = new DataParameter[] {
                    //dataParameter3,
                    dataParameter,
                    //dataParameter2,
                };
                client.Read(dps); // 批量读取


                foreach (var item in dps) // 遍历结果
                {
                    Console.WriteLine(string.Join(" ", item.DataBytes.Select(b => b.ToString("X2")))); // 输出结果
                }

                // 将读取的数据转换成可以看懂的数据类型
                List<float> str =
                    client.GetDatas<float>(dataParameter.DataBytes.ToArray()); // 获取数据

            }
            #endregion

            #region 通过地址一次只能读取一个区域数据
            Console.WriteLine("");
            //byte[] data_bytes = client.Read("VW100", 2);
            //byte[] data_bytes = client.Read("DB1.DBB100", 6);
            byte[] data_bytes = client.Read("Q0.5"); // 只能读取一个位
            Console.WriteLine(string.Join(" ", data_bytes.Select(b => b.ToString("X2"))));
            // 将读取的数据转换成可以看懂的数据类型
            List<bool> str1 =
                    client.GetDatas<bool>(data_bytes.ToArray()); // 获取数据
            #endregion
        }

        /// <summary>
        /// 测试PLC写入方法
        /// </summary>
        static void CustomLib_WriteTest()
        {
            S7Client client = new S7Client();
            // 真机IP地址   200Smart   Stup 7进行检查/专用的编程工具
            //client.Connect("192.168.1.100", 0, 0);
            // 虚拟机IP地址（启动PLC仿真器）     使用博途进行检查/专用的编程工具
            client.Connect("192.168.174.128", 0, 0);

            #region 一次写入多个不同区域数据
            if (true)
            {
                // 一交性写入多个不同区域的数据
                // DB1.DBW100  : 123
                DataParameter dataParameter = new DataParameter(); // 请求参数
                dataParameter.Area = Areas.DB; // 区域
                dataParameter.DBNumber = 1; // 数据库编号
                dataParameter.PVarType = ParameterVarType.BYTE; // 数据类型
                dataParameter.Count = 2; // 数据个数
                dataParameter.ByteAddress = 100; // 数据地址
                dataParameter.DataBytes = new byte[] { 0x00, 0x7B };//123
                dataParameter.DVarType = DataVarType.BYTE; // 数据类型

                // DB1.DBB10 : 123\124\125
                DataParameter dataParameter2 = new DataParameter(); // 请求参数
                dataParameter2.Area = Areas.DB; // 区域
                dataParameter2.DBNumber = 1;    // 数据库编号
                dataParameter2.PVarType = ParameterVarType.WORD; // 数据类型
                dataParameter2.Count = 3;   // 数据个数
                dataParameter2.ByteAddress = 10;    // 数据地址
                dataParameter2.DataBytes = new byte[] { 0x00, 0x7B, 0x00, 0x7C, 0x00, 0x7D };//123-124-125
                dataParameter2.DVarType = DataVarType.BYTE; // 数据类型

                // Q0.5 : 0
                DataParameter dataParameter3 = new DataParameter(); // 请求参数
                dataParameter3.Area = Areas.Q;  // 区域
                dataParameter3.PVarType = ParameterVarType.BIT; // 数据类型
                dataParameter3.BitAddress = 5; // 位地址
                dataParameter3.DataBytes = new byte[] { 0x00 }; // 0
                dataParameter3.DVarType = DataVarType.BIT; // 数据类型

                DataParameter[] dps = new DataParameter[] {
                    dataParameter,
                    dataParameter2,
                    dataParameter3,
                };
                client.Write(dps); // 批量写入

                Console.WriteLine("写入完成");
            }
            #endregion

            #region 通过地址一次只能写入一个区域数据
            #region 16进制数据写入
            client.Write("VW20", new byte[] { 0x00, 0x0A });
            client.Write("VB22", new byte[] { 0x0B, 0x0C });
            #endregion

            #region 10进制方式写入数据
            byte[] datas = client.GetBytes<float>(-20.2f, 6.5f, 66.6f);
            client.Write("DB1.DBD12", datas);
            byte[] datas1 = client.GetBytes<short>(-20, 1000, 666);
            client.Write("DB1.DBB22", datas1);
            #endregion

            #region bool类型写入
            client.Write("Q0.6", new byte[] { 0x01 });
            #endregion
            #endregion
        }

        /// <summary>
        /// PLC运行和停止使用方法
        /// </summary>
        static void CustomLib_Run_Stop()
        {
            S7Client client = new S7Client();
            client.Connect("192.168.1.100", 0, 0);

            client.Stop(); // 停止PLC

            client.Run(); // 运行PLC
        }

        /// <summary>
        /// PLC读取时间、设置时间使用方法
        /// </summary>
        static void CustomLib_Read_Write_Time()
        {
            S7Client client = new S7Client();
            client.Connect("192.168.1.100", 0, 0);

            DateTime dt = client.GetTime(); // 获取PLC时间

            client.SetTime(new DateTime(2025, 10, 1, 20, 20, 20)); // 设置PLC时间
        }
        #endregion
    }
}
